package com.ichengzi.audit.human.repository.es.config;

import co.elastic.clients.elasticsearch.ElasticsearchClient;
import co.elastic.clients.json.jackson.JacksonJsonpMapper;
import co.elastic.clients.transport.ElasticsearchTransport;
import co.elastic.clients.transport.TransportUtils;
import co.elastic.clients.transport.rest_client.RestClientTransport;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.Header;
import org.apache.http.HttpHost;
import org.apache.http.auth.AuthScope;
import org.apache.http.auth.UsernamePasswordCredentials;
import org.apache.http.impl.client.BasicCredentialsProvider;
import org.apache.http.message.BasicHeader;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestClientBuilder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import javax.net.ssl.SSLContext;

/**
 * @author lihn
 */

@Configuration
public class ElasticSearchConfig {

    /** ip地址 */
    @Value("${elasticsearch.host}")
    private String host;

    /** 端口号 */
    @Value("${elasticsearch.port}")
    private Integer port;

    /** https */
    @Value("${elasticsearch.scheme}")
    private String scheme;

    /** 用户名 */
    @Value("${elasticsearch.username}")
    private String username;

    /** 密码 */
    @Value("${elasticsearch.password}")
    private String password;

    /** apiKey */
    @Value("${elasticsearch.apiKey}")
    private String apiKey;

    /**
     * ssl证书指纹
     * 生成命令：openssl x509 -fingerprint -sha256 -noout -in /usr/local/elasticsearch-8.10.3/config/certs/http_ca.crt
     */

    @Value("${elasticsearch.fingerprint}")
    private String fingerprint;


    /**
     * 注入IOC容器
     */
    @Bean
    public ElasticsearchClient elasticsearchClient(){
        // 使用指纹（fingerprint）方式设置elasticsearch的SSL认证
        SSLContext sslContext = TransportUtils.sslContextFromCaFingerprint(fingerprint);
        // 封装es路径
        RestClientBuilder builder = RestClient.builder(new HttpHost(host, port, scheme));

        builder.setHttpClientConfigCallback(hc -> hc
                .setSSLContext(sslContext)
        );
        // 使用apiKey的方式认证
        if(StringUtils.isNotBlank(apiKey)){
            builder.setDefaultHeaders(new Header[]{
                    new BasicHeader("Authorization", "ApiKey " + apiKey)
            });
        }else{
            // 使用用户名、密码的方式认证
            if (StringUtils.isNotBlank(username) || StringUtils.isNotBlank(password)) {
                BasicCredentialsProvider credsProv = new BasicCredentialsProvider();
                credsProv.setCredentials(
                        AuthScope.ANY, new UsernamePasswordCredentials(username, password)
                );
                builder.setHttpClientConfigCallback(hc -> hc
                        .setDefaultCredentialsProvider(credsProv)
                );
            }
        }
        // 构建RestClient实例
        RestClient restClient = builder.build();
        // 创建ElasticsearchTransport对象，用于与Elasticsearch进行通信
        ElasticsearchTransport transport = new RestClientTransport(
                restClient, new JacksonJsonpMapper());
        return new ElasticsearchClient(transport);
    }
}